package ClientCommands;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.json.simple.JSONObject;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import Annotations.IsClientCommand;
import Commands.ClientCommandBase;
import Commands.ExecuteMethod;
import Helpers.ApplicationConfiguration;
import Helpers.ApplicationLogger;

@IsClientCommand
public class GetWeather extends ClientCommandBase<Map<String, String>> {

	public GetWeather()
	{
		setCommandName("GetWeather");
		setCommandDescription("Get Weather from google.com");
		setExecuteMethod(ExecuteMethod.ServerOnly);
	}
	
	@Override
	protected void ExecuteInternal() throws IOException {
		
		URL url = new URL(ApplicationConfiguration.getInstance().GetWeatherFeedURI());
		URLConnection uc = url.openConnection();         
		BufferedReader in = new BufferedReader(new InputStreamReader(uc.getInputStream())); 
		String inputLine;     
		String outLine = "";
		while ((inputLine = in.readLine()) != null)              
			outLine += inputLine;         
		in.close();
		setResult(GetDataFromFeed(outLine));
	}
	
	 private Map<String, String> GetDataFromFeed(String feed)
     {
		 Map<String, String> result = new HashMap<String, String>();
			
			DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
			DocumentBuilder db = null;
			Document doc = null;
			
			try {
				db = dbf.newDocumentBuilder();
			} catch (ParserConfigurationException e) {
				ApplicationLogger.getInstance().LOG.error(e.getMessage());
			}
			 try {
				doc = db.parse(new InputSource(new ByteArrayInputStream(feed.getBytes("utf-8"))));
			} catch (SAXException e) {
				ApplicationLogger.getInstance().LOG.error(e.getMessage());
			} catch (IOException e) {
				ApplicationLogger.getInstance().LOG.error(e.getMessage());
			} 
			
			boolean isProblem = doc.getElementsByTagName("problem_cause").getLength() > 0;
			if(!isProblem)
			{
				XPathFactory factory = XPathFactory.newInstance();
				XPath xpath = factory.newXPath();
				XPathExpression condition_data_expr = null;
				XPathExpression temp_c_data_expr = null;
				Node condition_data = null;
				Node temp_c_data = null;
				
				try {
					condition_data_expr = xpath.compile("//current_conditions/condition/@data");
					temp_c_data_expr = xpath.compile("//current_conditions/temp_c/@data");
				} catch (XPathExpressionException e) {
					ApplicationLogger.getInstance().LOG.error(e.getMessage());
				}

				try {
					condition_data = (Node)condition_data_expr.evaluate(doc, XPathConstants.NODE);
					temp_c_data = (Node)temp_c_data_expr.evaluate(doc, XPathConstants.NODE);
				} catch (XPathExpressionException e) {
					ApplicationLogger.getInstance().LOG.error(e.getMessage());
				}
				result.put("condition", condition_data.getNodeValue());
				result.put("temp_c", temp_c_data.getNodeValue());
		        result.put("img_path", ApplicationConfiguration.getInstance().GetCurrentWeatherImgPathByName(condition_data.getNodeValue()));
			}
			else
			{
				ApplicationLogger.getInstance().LOG.info("Server problem");
			}
		
        return result; 
     }

	public void FillFromJSON(JSONObject jobj) {
		
	}
	
	public String toJSONString()
	{
		return  super.toJSONString();
	}
}
